/*****************************************************************
|
|   Platinum - AV Media Controller (Media Renderer Control Point)
|
| Copyright (c) 2004-2010, Plutinosoft, LLC.
| All rights reserved.
| http://www.plutinosoft.com
|
| This program is free software; you can redistribute it and/or
| modify it under the terms of the GNU General Public License
| as published by the Free Software Foundation; either version 2
| of the License, or (at your option) any later version.
|
| OEMs, ISVs, VARs and other distributors that combine and 
| distribute commercially licensed software with Platinum software
| and do not wish to distribute the source code for the commercially
| licensed software under version 2, or (at your option) any later
| version, of the GNU General Public License (the "GPL") must enter
| into a commercial license agreement with Plutinosoft, LLC.
| licensing@plutinosoft.com
| 
| This program is distributed in the hope that it will be useful,
| but WITHOUT ANY WARRANTY; without even the implied warranty of
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
| GNU General Public License for more details.
|
| You should have received a copy of the GNU General Public License
| along with this program; see the file LICENSE.txt. If not, write to
| the Free Software Foundation, Inc., 
| 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
| http://www.gnu.org/licenses/gpl-2.0.html
|
****************************************************************/

#ifndef _PLT_REMOUTE_CONTROLER_H_
#define _PLT_REMOUTE_CONTROLER_H_

/*----------------------------------------------------------------------
|   includes
+---------------------------------------------------------------------*/
#include "PltCtrlPoint.h"
#include "PltMediaItem.h"

/*----------------------------------------------------------------------
|   Defines
+---------------------------------------------------------------------*/
typedef NPT_List<NPT_String> PLT_StringList;

typedef struct {
    NPT_String keyboard;
    NPT_String touchscreen;
    NPT_String mouse;
} PLT_DeviceInputTypes;

typedef struct {
    NPT_UInt32 xmax;
    NPT_UInt32 xmin;
    NPT_UInt32 ymax;
    NPT_UInt32 ymin;
} PLT_TouchScreenInfo;

/*----------------------------------------------------------------------
|   PLT_RemouteControlerDelegate
+---------------------------------------------------------------------*/
class PLT_RemouteControlerDelegate
{
public:
    virtual ~PLT_RemouteControlerDelegate() {}

    virtual bool OnRCSAdded(PLT_DeviceDataReference& /* device */) { return true; }
    virtual void OnRCSRemoved(PLT_DeviceDataReference& /* device */) {}
    virtual void OnRCSStateVariablesChanged(PLT_Service*                  /* service */, 
                                           NPT_List<PLT_StateVariable*>* /* vars */) {}

    // RemouteControlServer
    virtual void OnGetDeviceInputTypesResult(
        NPT_Result               /* res */, 
        PLT_DeviceDataReference& /* device */,
        PLT_DeviceInputTypes*    /* typeinfos */, 
        void*                    /* userdata */) {}
	virtual void OnGetTouchScreenBoundaryResult(
        NPT_Result               /* res */,
        PLT_DeviceDataReference& /* device */,
        const char*              /* boundary */,
        void*                    /* userdata */) {}
	virtual void OnCmdRequestResult(
        NPT_Result               /* res */,
        PLT_DeviceDataReference& /* device */,
        const char* 		/*curcmd*/,
        const char*              /* cmdresult */,
        void*                    /* userdata */){}
	virtual void OnSetTouchEventResult(
        NPT_Result               /* res */,
        PLT_DeviceDataReference& /* device */,
        void*                    /* userdata */){}
};

/*----------------------------------------------------------------------
|   PLT_RemouteControler
+---------------------------------------------------------------------*/
class PLT_RemouteControler : public PLT_CtrlPointListener
{
public:
    PLT_RemouteControler(PLT_CtrlPointReference&      ctrl_point, 
                        PLT_RemouteControlerDelegate* delegate = NULL);
    virtual ~PLT_RemouteControler();

    // public methods
    virtual void SetDelegate(PLT_RemouteControlerDelegate* delegate) {
        m_Delegate = delegate;
    }

    // PLT_CtrlPointListener methods
    virtual NPT_Result OnDeviceAdded(PLT_DeviceDataReference& device);
    virtual NPT_Result OnDeviceRemoved(PLT_DeviceDataReference& device);
    virtual NPT_Result OnActionResponse(NPT_Result res, PLT_ActionReference& action, void* userdata);
    virtual NPT_Result OnEventNotify(PLT_Service* service, NPT_List<PLT_StateVariable*>* vars);

    // VariableStates    
    virtual NPT_Result GetProtocolInfoSink(const NPT_String& device_uuid, NPT_List<NPT_String>& sinks);

     // methods
    virtual NPT_Result FindRemouteControlServer(const char* uuid, PLT_DeviceDataReference& device);
    virtual NPT_Result FindMatchingProtocolInfo(NPT_List<NPT_String>& sinks, const char* protocol_info);
    virtual NPT_Result FindBestResource(PLT_DeviceDataReference& device, PLT_MediaObject& item, NPT_Cardinal& resource_index);

	NPT_Result SetDeviceInputStates(PLT_DeviceDataReference& device,NPT_UInt32 instance_id,const char* states,void* userdata);
	NPT_Result SetTouchScreenEvent(PLT_DeviceDataReference& device,NPT_UInt32 instance_id,const char* eventdata,void* userdata);
	NPT_Result GetTouchScreenBoundary(PLT_DeviceDataReference& device,  NPT_UInt32 instance_id, void* userdata);
	NPT_Result CmdRequest(PLT_DeviceDataReference& device,NPT_UInt32 instance_id,const char* cmd,const char* param,void* userdata);

private:
    NPT_Result InvokeActionWithInstance(PLT_ActionReference& action, NPT_UInt32 instance_id, void* userdata = NULL);

//////
	NPT_Result OnGetDeviceInputTypesResponse(NPT_Result res, PLT_DeviceDataReference& device, PLT_ActionReference& action, void* userdata);
	NPT_Result OnGetTouchScreenBoundaryResponse(NPT_Result res,PLT_DeviceDataReference& device,PLT_ActionReference& action, void* userdata);
	NPT_Result OnCmdRequestResponse(NPT_Result res,PLT_DeviceDataReference& device,PLT_ActionReference& action, void* userdata);

public:
    static void ParseCSV(const char* csv, PLT_StringList& values) {
        const char* start = csv;
        const char* p = start;

        // look for the , character
        while (*p) {
            if (*p == ',') {
                NPT_String val(start, (int)(p-start));
                val.Trim(' ');
                values.Add(val);
                start = p + 1;
            }
            p++;
        }

        // last one
        NPT_String last(start, (int)(p-start));
        last.Trim(' ');
        if (last.GetLength()) {
            values.Add(last);
        }
    }

private:
    PLT_CtrlPointReference                m_CtrlPoint;
    PLT_RemouteControlerDelegate*         m_Delegate;
    NPT_Lock<PLT_DeviceDataReferenceList> m_RemountControlers;
};

typedef NPT_Reference<PLT_RemouteControler> PLT_RemouteControlerReference;

#endif /* _PLT_REMOUTE_CONTROLER_H_ */
